home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Enigma Amiga Life 112
/
EnigmaAmiga112CD.iso
/
dalla rivista
/
news
/
orbit
/
source
/
missile.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-01
|
9KB
|
441 lines
/*
Amiga port by Oliver Gantert
27.04.2000 - fixed some compiler warnings
*/
/*
ORBIT, a freeware space combat simulator
Copyright (C) 1999 Steve Belczyk <steve1@genesis.nred.ma.us>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "orbit.h"
void InitMissiles()
/*
* Set up missile structures
*/
{
int i;
/* Mark all missiles as unused */
for (i=0; i<NMSLS; i++)
{
msl[i].age = 0.0;
}
}
int FindMissile()
/*
* Find unused missile
*/
{
int i, oldest;
double maxage;
/* Look for free missile, or oldest */
for (i=0; i<NMSLS; i++)
{
if (msl[i].age == 0.0) return (i);
if (i == 0)
{
maxage = msl[i].age;
oldest = i;
}
else
{
if (msl[i].age > maxage)
{
maxage = msl[i].age;
oldest = i;
}
}
}
/* None free, return oldest */
return (oldest);
}
void FireMissile (double *pos, double *vel, double *dir, int friendly, int wep, int owner)
/*
* Fire missile at the given location and velocity, in
* the specified direction
*/
{
int m;
double v[3];
/* Find a free missile */
m = FindMissile();
/* Set it up */
msl[m].age = deltaT;
Vset (msl[m].pos, pos);
if (friendly && !am_client && !am_server)
{
Vmul (v, player.up, -0.005);
Vadd (msl[m].pos, msl[m].pos, v);
}
Vmul (msl[m].vel, dir, weapon[wep].speed);
Vadd (msl[m].vel, msl[m].vel, vel);
msl[m].friendly = friendly;
msl[m].weapon = wep;
msl[m].owner = owner;
/* Play the sound */
/* if (sound) PlaySound ("phaser.wav", NULL, SND_ASYNC | SND_FILENAME); */
if (sound) PlayAudio (SOUND_FIRE);
}
void MoveMissiles()
/*
* Move all the missiles
*/
{
int m, t, p;
double v[3], deltav[3];
/* Loop through missiles */
for (m=0; m<NMSLS; m++)
{
/* If missile in use */
if (msl[m].age > 0.0)
{
/* Bump age */
msl[m].age += deltaT;
/* See if expired */
if (msl[m].age > weapon[msl[m].weapon].expire)
{
DestroyMissile (m);
return;
}
/* See if missile has hit planet */
if ((-1) != (p = InsidePlanet (msl[m].pos)))
{
/* Missile has hit planet */
/* Move point of impact just above planet surface */
Vsub (v, msl[m].pos, planet[p].pos);
Normalize (v);
Vmul (v, v, planet[p].radius*1.05);
Vadd (v, v, planet[p].pos);
Boom (v, weapon[msl[m].weapon].yield/100.0);
DestroyMissile (m);
return;
}
/* See if missile hit a target */
if ((-1) != (t = HitTarget (m)))
{
/* Missle hit target */
MissileHitTarget (m, t);
return;
}
/* See if missile hit player */
if (!msl[m].friendly && !am_client &&
(state != STATE_DEAD1) && (state != STATE_DEAD2) )
{
if (TARGDIST2 > Dist2 (msl[m].pos[0], msl[m].pos[1], msl[m].pos[2],
player.pos[0], player.pos[1], player.pos[2]))
{
/* Missile hit player */
MissileHitPlayer (m);
return;
}
}
/* Else update its position */
if (gravity)
{
Gravity (deltav, msl[m].pos);
Vadd (msl[m].vel, msl[m].vel, deltav);
}
Vmul (v, msl[m].vel, deltaT);
Vadd (msl[m].pos, msl[m].pos, v);
}
}
}
void DestroyMissile (int m)
/*
* Missile has expired
*/
{
msl[m].age = 0.0;
}
void DrawMissiles ()
/*
* Draw all the missiles
*/
{
int m;
for (m=0; m<NMSLS; m++)
{
if (msl[m].age > 0.0) DrawMissile (m);
}
}
void DrawMissile (int m)
/*
* Draw this missile
*/
{
glPushMatrix();
glDisable (GL_LIGHTING);
glDisable (GL_CULL_FACE);
switch (weapon[msl[m].weapon].renderer)
{
case 0: DrawMissile0 (m);
break;
case 1: DrawMissile1 (m);
break;
case 2: DrawMissile2 (m);
break;
case 3: DrawMissile3 (m);
break;
case 4: DrawMissile4 (m);
break;
}
glEnable (GL_CULL_FACE);
glEnable (GL_LIGHTING);
glPopMatrix();
}
void DrawMissile0 (int m)
{
double r, s, v[3];
/* Figure how much to spin missile */
r = absT - ((double)(int)absT);
s = 360.0 * r;
glColor3fv (weapon[msl[m].weapon].color);
Vsub (v, msl[m].pos, player.pos);
glTranslated (v[0], v[1], v[2]);
glRotated (s, 0.3, 1.0, 0.6);
glBegin (GL_LINES);
glVertex3d (-0.01, 0.0, 0.0);
glVertex3d ( 0.01, 0.0, 0.0);
glVertex3d (0.0, -0.01, 0.0);
glVertex3d (0.0, 0.01, 0.0);
glVertex3d (0.0, 0.0, -0.01);
glVertex3d (0.0, 0.0, 0.01);
glEnd();
}
void DrawMissile1 (int m)
{
double r, s, v[3];
/* Figure how much to spin missile */
r = absT - ((double)(int)absT);
s = 360.0 * r;
glColor3fv (weapon[msl[m].weapon].color);
Vsub (v, msl[m].pos, player.pos);
glTranslated (v[0], v[1], v[2]);
glRotated (s, 0.3, 1.0, 0.6);
glBegin (GL_LINES);
glVertex3d (-0.01, 0.0, 0.0);
glVertex3d ( 0.01, 0.0, 0.0);
glVertex3d (0.0, -0.01, 0.0);
glVertex3d (0.0, 0.01, 0.0);
glVertex3d (0.0, 0.0, -0.01);
glVertex3d (0.0, 0.0, 0.01);
glEnd();
}
void DrawMissile2 (int m)
{
double v1[3], v2[3], v3[3], v4[4], vel[3], v[3];
glColor3fv (weapon[msl[m].weapon].color);
Vsub (v, msl[m].pos, player.pos);
glTranslated (v[0], v[1], v[2]);
Vmul (vel, msl[m].vel, 0.1);
glBegin (GL_QUADS);
v1[0] = 0.01; v1[1] = 0.0; v1[2] = 0.0;
v2[0] = -0.01; v2[1] = 0.0; v2[2] = 0.0;
Vsub (v3, v2, vel);
Vsub (v4, v1, vel);
glVertex3dv (v1);
glVertex3dv (v2);
glVertex3dv (v3);
glVertex3dv (v4);
v1[0] = 0.0; v1[1] = 0.01; v1[2] = 0.0;
v2[0] = 0.0; v2[1] = -0.01; v2[2] = 0.0;
Vsub (v3, v2, vel);
Vsub (v4, v1, vel);
glVertex3dv (v1);
glVertex3dv (v2);
glVertex3dv (v3);
glVertex3dv (v4);
v1[0] = 0.0; v1[1] = 0.0; v1[2] = 0.01;
v2[0] = 0.0; v2[1] = 0.0; v2[2] = -0.01;
Vsub (v3, v2, vel);
Vsub (v4, v1, vel);
glVertex3dv (v1);
glVertex3dv (v2);
glVertex3dv (v3);
glVertex3dv (v4);
glEnd();
}
void DrawMissile3 (int m)
{
double r, s, v[3];
/* Figure how much to spin missile */
r = absT - ((double)(int)absT);
s = 360.0 * r;
glColor3fv (weapon[msl[m].weapon].color);
Vsub (v, msl[m].pos, player.pos);
glTranslated (v[0], v[1], v[2]);
glRotated (s, 0.3, 1.0, 0.6);
glScaled (0.01, 0.01, 0.01);
glutSolidTetrahedron ();
}
void DrawMissile4 (int m)
{
int i;
double v[3], u[3];
glColor3fv (weapon[msl[m].weapon].color);
Vsub (u, msl[m].pos, player.pos);
glTranslated (u[0], u[1], u[2]);
glBegin (GL_LINE_LOOP);
for (i=0; i<6; i++)
{
v[0] = rnd(0.04) - 0.01;
v[1] = rnd(0.04) - 0.01;
v[2] = rnd(0.04) - 0.01;
glVertex3dv (v);
}
glEnd();
}
void MissileHitPlayer (int m)
/*
* Missile m hit player. Ouch!
*/
{
/* Flash screen red */
palette_flash = 2;
/* Damage shields */
player.shields -= weapon[msl[m].weapon].yield;
/* Get rid of missile */
DestroyMissile (m);
/* See if player died */
if (vulnerable && (player.shields < 0.0) && !am_client)
{
if (am_server)
{
/* Tell other clients */
NetDestroyClient (server.client, FindClientByTarget (msl[m].owner));
NetPlayerDies();
}
else
{
/* Single player games, reset */
InitPlayer();
ReadMission (mission.fn);
Mprint ("You were killed! Restarting mission.");
}
}
if (player.shields < 0.0) player.shields = 100.0;
}
void MissileHitTarget (int m, int t)
/*
* Missile m hit target t. Go get 'em!
*/
{
int e;
Boom (msl[m].pos, weapon[msl[m].weapon].yield/100.0);
target[t].shields -= weapon[msl[m].weapon].yield;
if (target[t].shields < 0.0) target[t].shields = 0.0;
/* Announce to network */
if (am_server) NetHitTarget (t, m);
/* See if we set off an event */
for (e=0; e<NEVENTS; e++)
{
if (event[e].pending &&
event[e].enabled &&
(event[e].trigger == EVENT_SHIELDS) &&
(!strcasecmp (event[e].cvalue, target[t].name)) &&
(target[t].shields <= event[e].fvalue) )
{
EventAction (e);
}
}
/* See if target is destroyed */
if (!am_client && target[t].shields <= 0.0)
{
/* Announce to network */
NetDestroyTarget (t, m);
/* Kablooie! */
Boom (target[t].pos, 1.0);
if (!am_server) DestroyTarget (t);
if (am_server) target[t].shields = 100.0;
}
DestroyMissile (m);
}